package com.xiaotu.spider.project.pageprocessor;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;
import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.util.FileUtil;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.SepratorUtil;
import com.xiaotu.spider.APageProcessor;

/**
 * @类名 DouBanCommentPageProcessor
 * @日期 2017年6月1日
 * @作者 王艳龙
 * @功能 豆瓣评论数据爬取
 */
@Component("DouBanCommentPageProcessor")
@Scope("prototype")
public class DouBanCommentPageProcessor extends APageProcessor {
	
	private static final String COMMENT_REVIEWER = "评论人";
	private static final String COMMENT_TIME = "评论时间";
	private static final String COM_CONTENT = "评论内容";
	private static final String COMMENT_VOTES = "评论权重";
	private static final String COMMENT_LEVEL = "评论等级";
	private String fileName;

	private static final List<String> LABELS_ALL = Arrays.asList("评论人", "评论时间",
			"评论内容", "评论权重", "评论等级");
	

	@Override
	public void initRunParams(Map<String, Object> map)
	{
		if (map.get("fileName") == null)
			throw new SpiderException(
					SpiderExceptionCode.PageProcessorParameterErrorException);
		fileName = FileUtil
				.getCacheFilePath(map.get("fileName") + StringUtils.EMPTY);
	}
	
	@Override
	protected Request getStartRequest(JSONObject target) {
		//String url ="https://movie.douban.com/subject/26430092/comments?start=0&limit=20&sort=new_score&status=P";
		target.putAll(this.getOtherTarget());
		return new Request(target.getString("url"));
	}

	@Override
	public void process(Page page) {
		List<String> divList = page.getHtml()
				.xpath("//div[@class='comment-item']").all();
		if (divList == null || divList.isEmpty())
			throw new SpiderException(SpiderExceptionCode.DataInvalideException);
		Map<String, String> map = new HashMap<String, String>();
		for (String divStr : divList) {
			Html divObj = new Html(divStr);
			for (String key : LABELS_ALL) {
				if (key.contains(COMMENT_REVIEWER)
						|| key.contains(COMMENT_LEVEL)) {
					this.parseTitle(divObj, map, key);
				}
				if (key.contains(COMMENT_TIME) || key.contains(COM_CONTENT)
						|| key.contains(COMMENT_VOTES)) {
					this.parseBaseinfo(divObj, map, key);
				}
			}
			StringBuffer buffer = new StringBuffer();
			for (String key : LABELS_ALL)
				buffer.append(SepratorUtil.SEP_PIPE
						+ (map.containsKey(key) ? map.get(key)
								: StringUtils.EMPTY));
					FileUtil.writeFile(fileName, buffer.toString()
							+ SepratorUtil.LINE_SEPRATOR);
		}
		int pageMax =202;
		String current = page.getHtml()
				.xpath("//div[@class='center']/a[@class='next']/@href").get();
		String pageSize =current.substring(current.indexOf("start=")+6, current.indexOf("&limit"));
		System.out.println(Integer.parseInt(pageSize) >= pageMax);
		if (StringUtils.isNotEmpty(pageSize)){
			pageSize = RegexUtils.regexSearch(RegexUtils.REGEX_INTEGER, pageSize);
			if (StringUtils.isNotEmpty(pageSize))
			{
				if (pageMax >= Integer.parseInt(pageSize))
					PageUtils.addTargetRequest(page,
							current,
							page.getRequest().getExtras());
			}
		}
		//无条数限制，爬取所有数据
		/*String current = page.getHtml()
				.xpath("//div[@class='center']/a[@class='next']/@href").get();
		if (current == null || current.isEmpty())
			return;
		if (StringUtils.isNotEmpty(current)){
			PageUtils.addTargetRequest(page,current,page.getRequest().getExtras());
		}*/
	}


	/**
	 * TEXT文本基本信息解析
	 * @param html 页面元素
	 * @param map缓存
	 */
	private void parseBaseinfo(Html html, Map<String, String> map, String key) {
		StringBuffer buffer = new StringBuffer();
		if (key.contains(COMMENT_TIME)) {
			String comTime = html.xpath("//span[@class='comment-time']/@title")
					.get();
			if (comTime == null || comTime.isEmpty())
				return;
			map.put(COMMENT_TIME,
					buffer.append(comTime).append(SepratorUtil.SEP_COMMA_EN)
							.toString());

		} else if (key.contains(COM_CONTENT)) {
			String comContent = html.xpath("//div[@class='comment']/p/text()")
					.get();
			if (comContent == null || comContent.isEmpty())
				return;
			map.put(COM_CONTENT,
					buffer.append(comContent).append(SepratorUtil.SEP_COMMA_EN)
							.toString());

		} else if (key.contains(COMMENT_VOTES)) {
			String votes = html.xpath("//span[@class='comment-vote']/span[@class='votes']/text()").get();
			if (votes == null || votes.isEmpty())
				return;
			String show_login = html.xpath(
					"//span[@class='comment-vote']/a/text()").get();
			if (show_login == null || show_login.isEmpty())
				return;
			String comment_votes = buffer.append(votes)
					.append(SepratorUtil.SEP_SPACE_EN).append(show_login)
					.append(SepratorUtil.SEP_COMMA_EN).toString();
			map.put(COMMENT_VOTES, comment_votes);
		}
	}

	/**
	 * 标签标题信息解析
	 * @param html页面元素
	 * @param map缓存
	 */
	private void parseTitle(Html html, Map<String, String> map, String key) {
		StringBuffer buffer = new StringBuffer();
		if (key.contains(COMMENT_REVIEWER)) {
			String comReviewer = html.xpath("//div[@class='avatar']/a/@title")
					.get();
			if (comReviewer == null || comReviewer.isEmpty())
				return;
			map.put(COMMENT_REVIEWER,
					buffer.append(comReviewer)
							.append(SepratorUtil.SEP_COMMA_EN).toString());

		} else if (key.contains(COMMENT_LEVEL)) {
			List<String> comLevelClass = html.xpath(
					"//span[@class='comment-info']/span/@class").all();
			for(String cla: comLevelClass){
				if(cla.contains("allstar")){
					String comLevel = html.xpath(
							"//span[@class='"+cla+"']/@title").get();
					map.put(COMMENT_LEVEL,
							buffer.append(comLevel)
							.append(SepratorUtil.SEP_COMMA_EN).toString());
				}
			}

		}
	}
	
	@Override
	protected String getSpiderType() {
		return "DouBanComment";
	}

	@Override
	public String getPageDataType(Page page) {
		return "DouBanComment";
	}

}